package pe.edu.upc.e41a.javasoft.jsf;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;

import javax.annotation.PostConstruct;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;

import org.primefaces.context.RequestContext;
import org.primefaces.event.CloseEvent;
import org.primefaces.event.NodeCollapseEvent;
import org.primefaces.event.NodeExpandEvent;
import org.primefaces.event.NodeSelectEvent;
import org.primefaces.event.NodeUnselectEvent;
import org.primefaces.model.DefaultTreeNode;
import org.primefaces.model.TreeNode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.roo.addon.serializable.RooSerializable;

import pe.edu.upc.e41a.javasoft.domain.Categoria;
import pe.edu.upc.e41a.javasoft.domain.Publicacion;
import pe.edu.upc.e41a.javasoft.service.CategoriaService;

@Configurable
@ManagedBean(name = "ejemploBean")
@SessionScoped
@RooSerializable
public class EjemploBean implements Serializable {

	private static final long serialVersionUID = 1L;
	private static final Logger LOG = LoggerFactory
			.getLogger(EjemploBean.class);

	@Autowired
	CategoriaService categoriaService;

	private String name = "Categorias";

	private Categoria categoria;

	private List<Categoria> allCategorias;

	private List<Categoria> listaCategorias;

	private boolean dataVisible = false;

	private List<String> columns;

	private boolean createDialogVisible = false;

	private List<Publicacion> selectedPublicacions;

	private List<Categoria> selectedCategorias;

	private TreeNode root;
	private TreeNode selectedNode;
	private TreeNode[] selectedNodes;
	private Categoria categoriaArbol; 
	
	@PostConstruct
	public void init() {

		columns = new ArrayList<String>();
		columns.add("nombre");
		columns.add("descripcion");
		listaCategorias = categoriaService.findAllCategorias();
		
		crearArbol(categoriaArbol,"-",root);

	}

	public String getName() {
		return name;
	}
	
	public Categoria getCategoriaArbol() {
		if (categoriaArbol == null) {
			categoriaArbol = new Categoria();
		}
		return categoriaArbol;
	}

	public void setCategoriaArbol(Categoria categoriaArbol) {
		this.categoriaArbol = categoriaArbol;
	}
	
	public List<String> getColumns() {
		return columns;
	}

	public List<Categoria> getAllCategorias() {
		return allCategorias;
	}

	public List<Categoria> getListaCategorias() {
		return listaCategorias;
	}

	public void setAllCategorias(List<Categoria> allCategorias) {
		this.allCategorias = allCategorias;
	}

	public String findAllCategorias() {
		allCategorias = categoriaService.findAllCategorias();
		dataVisible = !allCategorias.isEmpty();
		return null;
	}


	public boolean isDataVisible() {
		return dataVisible;
	}

	public void setDataVisible(boolean dataVisible) {
		this.dataVisible = dataVisible;
	}

	public void setTreeNode(TreeNode treeNode) {
		this.root = treeNode;
	}

	public TreeNode getRoot() {
		return root;
	}

	public TreeNode getSelectedNode() {
		return selectedNode;
	}

	public void setSelectedNode(TreeNode selectedNode) {
		this.selectedNode = selectedNode;
	}

	public TreeNode[] getSelectedNodes() {  
        return selectedNodes;  
    }  
  
    public void setSelectedNodes(TreeNode[] selectedNodes) {  
        this.selectedNodes = selectedNodes;  
    }  
	public void displaySelectedSingle(ActionEvent event) {
		if (selectedNode != null) {
			FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_INFO,
					"Selected", selectedNode.getData().toString());

			FacesContext.getCurrentInstance().addMessage(null, message);

		}
	}

	public Categoria getCategoria() {
		if (categoria == null) {
			categoria = new Categoria();
		}
		return categoria;
	}

	public void setCategoria(Categoria categoria) {
		this.categoria = categoria;
	}

	public List<Publicacion> getSelectedPublicacions() {
		return selectedPublicacions;
	}

	public void setSelectedPublicacions(List<Publicacion> selectedPublicacions) {
		if (selectedPublicacions != null) {
			categoria.setPublicacions(new HashSet<Publicacion>(
					selectedPublicacions));
		}
		this.selectedPublicacions = selectedPublicacions;
	}

	public List<Categoria> completePadre(String query) {
		List<Categoria> suggestions = new ArrayList<Categoria>();
		for (Categoria categoria : categoriaService.findAllCategorias()) {
			String categoriaStr = String.valueOf(categoria.getNombre() + " "
					+ categoria.getDescripcion());
			if (categoriaStr.toLowerCase().startsWith(query.toLowerCase())) {
				suggestions.add(categoria);
			}
		}
		return suggestions;
	}

	public List<Categoria> getSelectedCategorias() {
		return selectedCategorias;
	}

	public void setSelectedCategorias(List<Categoria> selectedCategorias) {
		if (selectedCategorias != null) {
			categoria.setCategorias(new HashSet<Categoria>(selectedCategorias));
		}
		this.selectedCategorias = selectedCategorias;
	}

	public String onEdit() {
		if (categoria != null && categoria.getPublicacions() != null) {
			selectedPublicacions = new ArrayList<Publicacion>(
					categoria.getPublicacions());
		}
		if (categoria != null && categoria.getCategorias() != null) {
			selectedCategorias = new ArrayList<Categoria>(
					categoria.getCategorias());
		}
		return null;
	}

	public boolean isCreateDialogVisible() {
		return createDialogVisible;
	}

	public void setCreateDialogVisible(boolean createDialogVisible) {
		this.createDialogVisible = createDialogVisible;
	}

	public String displayList() {
		createDialogVisible = false;
		findAllCategorias();
		return "categoriaMaestro";
	}

	public String displayCreateDialog() {
		categoria = new Categoria();
		createDialogVisible = true;
		return "categoriaMaestro";
	}

	public String persist() {
		String message = "";
		if (categoria.getCodigo() != null) {
			categoriaService.updateCategoria(categoria);
			message = "Successfully updated";
		} else {
			categoriaService.saveCategoria(categoria);
			message = "Successfully created";
		}
		RequestContext context = RequestContext.getCurrentInstance();
		context.execute("createDialog.hide()");
		context.execute("editDialog.hide()");

		FacesMessage facesMessage = new FacesMessage(message);
		FacesContext.getCurrentInstance().addMessage(null, facesMessage);
		reset();
		return findAllCategorias();
	}

	public String delete() {
		categoriaService.deleteCategoria(categoria);
		FacesMessage facesMessage = new FacesMessage("Successfully deleted");
		FacesContext.getCurrentInstance().addMessage(null, facesMessage);
		reset();
		return findAllCategorias();
	}

	public void reset() {
		categoria = null;
		selectedPublicacions = null;
		selectedCategorias = null;
		createDialogVisible = false;
		root = null;
	}

	public void handleDialogClose(CloseEvent event) {
		reset();
	}

	public void onNodeExpand(NodeExpandEvent event) {
		FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_INFO,
				"Expanded", event.getTreeNode().toString());

		FacesContext.getCurrentInstance().addMessage(null, message);

	}

	public String getNodeChild() {
		return null;
	}

	public void onNodeCollapse(NodeCollapseEvent event) {
		FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_INFO,
				"Collapsed", event.getTreeNode().getData().toString());

		FacesContext.getCurrentInstance().addMessage(null, message);
	}

	public void onNodeSelect(NodeSelectEvent event) {
		FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_INFO,
				"Selected", event.getTreeNode().getData().toString());

		FacesContext.getCurrentInstance().addMessage(null, message);
	}

	public void onNodeUnselect(NodeUnselectEvent event) {
		FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_INFO,
				"Unselected", event.getTreeNode().getData().toString());

		FacesContext.getCurrentInstance().addMessage(null, message);
	}
	
	public String crearArbol(Categoria categoria,String prefix,TreeNode nodoRef){
		
		List<Categoria>listaCategoria=categoriaService.findCategoriasByPadre(categoria);
		if (listaCategoria.size()> 0) {
			Iterator it =listaCategoria.iterator();
			while (it.hasNext()) {
				if (root==null) {
				root = new DefaultTreeNode("Root", null);
				}
				Categoria category = (Categoria) it.next();
				TreeNode nodo = new DefaultTreeNode(category.getNombre(), nodoRef);
				//System.out.println(prefix+category.getNombre());
				crearArbol(category,prefix+"-",nodo);
			}
		}
		return null;
	}	

}
